package com.pig4cloud.pig.admin.mq;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pig.admin.api.entity.*;
import com.pig4cloud.pig.admin.mq.vo.RfidInfoVo;
import com.pig4cloud.pig.admin.mq.vo.SendRequestVo;
import com.pig4cloud.pig.admin.mq.vo.UpdateUserVo;
import com.pig4cloud.pig.admin.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 消费者处理器
 *
 * @author jyy
 * @date 2024-11-26
 */
@Slf4j
@Component
public class MqttMessageReceiver implements MessageHandler {

	@Resource
	private MqttConfiguration mqttConfiguration;
	@Resource
	private PrRfidService prRfidService;
	@Resource
	private PrDeviceService prDeviceService;
	@Resource
	private PrUserService prUserService;
	@Resource
	private MqttMessageSender mqttMessageSender;
	@Resource
	private PrUserRfidInfoService prUserRfidInfoService;
	@Resource
	private PrRfidLogService prRfidLogService;
	@Value("${spring.mqtt.devTopic}")
	private String devTopic;

	public static void main(String[] args) {
		String remarks = "远程开锁，证书归还成功，证书ID645BF9EF,证书名称苏九,位置4";
		String rfidDate = remarks.substring(remarks.indexOf("证书名称") + "证书名称".length());
		String rfidName = rfidDate.split(",")[0];
		String rfidAddress = rfidDate.split(",")[1].substring(2);
		System.out.println(rfidName);
		System.out.println(rfidAddress);
	}
    /**
     * 消息处理
     *
     * @param message 消息
     * @throws MessagingException 消息异常
     */
    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        try {
			// 获取消息Topic
            MessageHeaders headers = message.getHeaders();
            String topic = headers.get(MqttHeaders.RECEIVED_TOPIC).toString();
            log.info("[获取到的消息的topic]：{} ", topic);
            
            // 获取消息体
            String payload = (String) message.getPayload();
            log.info("[获取到的消息的payload]：{} ", payload);
			//获取rides前端的topic

            // 根据主题分别进行消息处理
            if (topic.contains("smart/")) {
                log.info("接收到jyy/的消息啦，快去处理");
                // TODO 数据处理 payload
				//处理发送信息

				//处理返回信息
				if(topic.contains("reply")){
					JSONObject reply = JSONObject.parseObject(payload);
					//设备主题信息
					String deviceId = reply.getString("deviceid");
					//消息类型
					String cmdType = reply.getString("cmdtype");
					String types = "01,02,03,04,05,06,07,08,09,10,11,12,13,14";
					if(types.contains(cmdType)){
						JSONObject data = reply.getJSONObject("data");
						String code = data.getString("code");
						if("500".equals(code)){
							notify(deviceId,data.getString("info"),500);
							if("05".equals(cmdType)){
								notify("take/"+deviceId,data.getString("info"),500);
							}
						}
					}

					if(StringUtils.isNotBlank(cmdType)){

						//同步钥匙信息
						if(cmdType.equals("18")){
							syncRfid(reply,deviceId);
						}else if(cmdType.equals("17")){
							//同步用户信息
							syncUser(reply, deviceId);
						}else if(cmdType.equals("19")){
							//同步用户与钥匙的关系
							List<PrUserRfidInfoEntity> prUserEntitieList = JSONObject.parseArray(reply.getString("data").replace(" ", ""), PrUserRfidInfoEntity.class);
							//获取设备信息
							PrDeviceEntity deviceInfo = getDeviceInfo(deviceId);
							for (PrUserRfidInfoEntity prUserRfidInfoEntity : prUserEntitieList) {
								prUserRfidInfoEntity.setDeviceId(deviceInfo.getId());
								prUserRfidInfoEntity.setDeviceSign(deviceInfo.getDevSign());
							}
							//先删除
							QueryWrapper<PrUserRfidInfoEntity> queryWrapper = new QueryWrapper<>();
							queryWrapper.lambda().eq(PrUserRfidInfoEntity::getDeviceSign, deviceId);
							prUserRfidInfoService.remove(queryWrapper);
							//保存同步的信息
							prUserRfidInfoService.saveBatch(prUserEntitieList);
							notify("bind/"+deviceInfo.getDevSign(),"用户证书绑定更新成功",200);
						}else if(cmdType.equals("01")){
							//锁定成功
							notify(deviceId,"锁定成功",200);
						}else if(cmdType.equals("02")){
							//解锁成功
							notify(deviceId,"解锁成功",200);
						}else if(cmdType.equals("03")){
							//关机成功
							notify(deviceId,"关机成功",200);
						}else if(cmdType.equals("04")){
							//重启成功
							notify(deviceId,"重启成功",200);
						}else if(cmdType.equals("05")){
							//开门成功
							notify(deviceId,"柜门已打开",200);


						}else if(cmdType.equals("15")){
							//取出钥匙的通知
							takeOut(cmdType, deviceId,reply);
							//状态为领取或者归还钥匙时，更新设备内的钥匙状态
							updateRfid(deviceId);
						}else if( cmdType.equals("16")){
							//归还钥匙 记录日志
							JSONObject data = reply.getJSONObject("data");
							String remarks = data.getString("remarks");
							//rfid
							String rfid = remarks.substring(remarks.indexOf("证书ID") + "证书ID".length(),"证书ID".length() + remarks.indexOf("证书ID") + 8);
							//rfidName
							String rfidDate = remarks.substring(remarks.indexOf("证书名称") + "证书名称".length());
							String rfidName = rfidDate.split(",")[0];
							String rfidAddress = rfidDate.split(",")[1].substring(2);
							//用户id
							String userId = data.getString("userId");
							//查询用户信息
							QueryWrapper<PrUserEntity> queryWrapper = new QueryWrapper<>();
							queryWrapper.lambda().eq(PrUserEntity::getUserId, userId)
									.eq(PrUserEntity::getDeviceSign, deviceId);
							PrUserEntity prUserEntity = prUserService.getOne(queryWrapper);
							//查询柜体信息
							QueryWrapper<PrDeviceEntity> entityQueryWrapper = new QueryWrapper<>();
							entityQueryWrapper.lambda().eq(PrDeviceEntity::getDevSign,deviceId);
							PrDeviceEntity prDeviceEntity = prDeviceService.getOne(entityQueryWrapper);

							PrRfidLogEntity prRfidLogEntity = new PrRfidLogEntity();
							prRfidLogEntity.setUserId(prUserEntity.getUserId());
							prRfidLogEntity.setUserName(prUserEntity.getUserName());
							prRfidLogEntity.setRealName(prUserEntity.getRealName());
							//在柜状态
							prRfidLogEntity.setOperateStatus("01");
							//是否远程
							prRfidLogEntity.setOperateType("0");
							prRfidLogEntity.setRfidName(rfidName);
							prRfidLogEntity.setRfidNum(rfid);
							prRfidLogEntity.setRfidColumn(rfidAddress);
							prRfidLogEntity.setDeviceSign(deviceId);
							prRfidLogEntity.setDeviceId(prDeviceEntity.getId());
							prRfidLogEntity.setDeviceName(prDeviceEntity.getName());
							prRfidLogService.save(prRfidLogEntity);
							//状态为领取或者归还钥匙时，更新设备内的钥匙状态
							updateRfid(deviceId);
						}else if(cmdType.equals("06")){
							//添加用户成功后同步用户信息
							updateUser(deviceId);

						}else if(cmdType.equals("07")){
							//修改用户成功后同步用户信息
							updateUser(deviceId);

						}else if(cmdType.equals("08")){
							//修改用户成功后同步用户信息

							updateUser(deviceId);

						}else if(cmdType.equals("12") || cmdType.equals("13")){
							JSONObject data = reply.getJSONObject("data");
							String code = data.getString("code");
							if(code.equals("200")){
								//更新绑定的用户状态
								SendRequestVo<UpdateUserVo> sendRequestVo = new SendRequestVo<>();
								UpdateUserVo updateUserVo = new UpdateUserVo();
								sendRequestVo.setData(updateUserVo);
								sendRequestVo.setDeviceid(deviceId);
								sendRequestVo.setType("send");
								String tic = String.format(devTopic,deviceId);
								//同步用户与标签信息
								sendRequestVo.setCmdtype("19");
								mqttMessageSender.send(deviceId,tic,0, JSONObject.toJSONString(sendRequestVo));
							}else{
								//更新失败
								notify("bind/"+reply.getString("deviceid"),data.getString("info"),500);

							}


						}
					}


				}
            }
			// ......
            // TODO else if（匹配其他题主），为了演示方便，这里用的String的contains()方法匹配主题，还可以用String的matches()方法，匹配正则表达式

        } catch (Exception e) {
            log.error(e.toString());
        }
    }

	private void updateUser(String deviceId) {
		SendRequestVo<UpdateUserVo> sendRequestVo = new SendRequestVo<>();
		UpdateUserVo updateUserVo = new UpdateUserVo();
		sendRequestVo.setData(updateUserVo);
		sendRequestVo.setDeviceid(deviceId);
		sendRequestVo.setType("send");
		sendRequestVo.setCmdtype("17");
		String tic = String.format(devTopic, deviceId);
		mqttMessageSender.send(deviceId,tic,0, JSONObject.toJSONString(sendRequestVo));
	}


	private void takeOut(String cmdType, String deviceId,JSONObject reply) {
		if(cmdType.equals("15")){
			//证书id
			String remarks = reply.getJSONObject("data").getString("remarks");
			String rfid = remarks.substring(remarks.indexOf("证书ID") + "证书ID".length(),"证书ID".length() + remarks.indexOf("证书ID") + 8);

			//通知前端取出成功
			notify("take/"+ deviceId,"取出成功",200);
			QueryWrapper<PrRfidLogEntity> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda()
					.eq(PrRfidLogEntity::getDeviceSign, deviceId)
					.eq(PrRfidLogEntity::getRfidNum,rfid);
			List<PrRfidLogEntity> prRfidLogEntities = prRfidLogService.list(queryWrapper);
			if(CollectionUtils.isNotEmpty(prRfidLogEntities)){
				prRfidLogEntities.get(0).setTakeStatus("0");
				prRfidLogService.updateById(prRfidLogEntities.get(0));
			}
		}



	}

	private void updateRfid(String deviceId) {
		SendRequestVo<RfidInfoVo> sendRequestVo = new SendRequestVo<RfidInfoVo>();
		RfidInfoVo rfidInfoVo = new RfidInfoVo();
		sendRequestVo.setData(rfidInfoVo);
		sendRequestVo.setDeviceid(deviceId);
		sendRequestVo.setType("send");
		sendRequestVo.setCmdtype("18");
		String tic = String.format(devTopic, deviceId);
		mqttMessageSender.send(deviceId,tic,0, JSONObject.toJSONString(sendRequestVo));
	}

	private void notify(String deviceSign,String message,Integer code) {
		JSONObject data = new JSONObject();
		data.put("code", code);
		data.put("message", message);
		data.put("deviceSign", deviceSign);
		mqttMessageSender.send(deviceSign,"/front/refresh/" + deviceSign,0, data.toJSONString());
	}


	private void syncUser(JSONObject reply, String deviceid) {
		List<PrUserEntity> prUserEntitieList = JSONObject.parseArray(reply.getString("data"), PrUserEntity.class);
		//获取设备信息
		PrDeviceEntity deviceInfo = getDeviceInfo(deviceid);

		for (PrUserEntity prUserEntity : prUserEntitieList) {
			prUserEntity.setDeviceSign(deviceInfo.getDevSign());
			prUserEntity.setDeviceName(deviceInfo.getName());
			prUserEntity.setDeviceId(deviceInfo.getId());
		}
		//先删除
		QueryWrapper<PrUserEntity> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(PrUserEntity::getDeviceSign,deviceInfo.getDevSign());
		prUserService.remove(queryWrapper);
		//保存同步的用户信息
		prUserService.saveBatch(prUserEntitieList);
		//通知前端用户信息同步完成
		notify(deviceInfo.getDevSign(),"用户信息同步成功",200);
		notify("updateUser/"+deviceInfo.getDevSign(),"用户信息同步成功",200);
	}

	private PrDeviceEntity getDeviceInfo(String deviceid) {
		QueryWrapper<PrDeviceEntity> queryWrapper = new  QueryWrapper<>();
		queryWrapper.lambda().eq(PrDeviceEntity::getDevSign, deviceid);
		return prDeviceService.getOne(queryWrapper);
	}

	private void syncRfid(JSONObject reply,String deviceId) {
		List<RfidInfoVo> rfidInfoVo = JSONObject.parseArray(reply.getString("data"), RfidInfoVo.class);
		//获取设备名称
		if(StringUtils.isNotBlank(deviceId)){
			PrDeviceEntity prDeviceEntity = getDeviceInfo(deviceId);
			List<PrRfidEntity> prRfidEntities = new ArrayList<>();
			//保存rfid信息 并通知前端同步成功
			for (RfidInfoVo infoVo : rfidInfoVo) {
				PrRfidEntity prRfidEntity = new PrRfidEntity();
				prRfidEntity.setGoodsId(infoVo.getGoodsId());
				prRfidEntity.setRfidName(infoVo.getKeyName());
				prRfidEntity.setRfidColumn(infoVo.getAdd());
				prRfidEntity.setRfidNum(infoVo.getUID());
				prRfidEntity.setRfidStatus(infoVo.getState());
				prRfidEntity.setDeviceId(prDeviceEntity.getId());
				prRfidEntity.setDeviveName(prDeviceEntity.getName());
				prRfidEntity.setDeviceSign(prDeviceEntity.getDevSign());
				prRfidEntities.add(prRfidEntity);
			}
			//删除已该设备下所有的rfid信息
			QueryWrapper<PrRfidEntity> rfidEntityQueryWrapper = new  QueryWrapper<>();
			rfidEntityQueryWrapper.lambda().eq(PrRfidEntity::getDeviceId,prDeviceEntity.getId());
			prRfidService.remove(rfidEntityQueryWrapper);
			//保存新的rfid信息
			prRfidService.saveBatch(prRfidEntities);
			//通知前端同步完成
			notify(prDeviceEntity.getDevSign(),"钥匙同步成功",200);
			notify("all","钥匙同步成功",200);
		}
	}
}

